package algo3.algothief.controlador;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import algo3.algothief.excepcion.CasoNoIniciadoException;
import algo3.algothief.excepcion.PaisInvalidoParaViajarDesdeElActualException;
import algo3.algothief.modelo.Juego;
import algo3.algothief.modelo.Pais;
import algo3.algothief.vista.VistaJuego;


public class ControladorViaje {

	private Juego juego;
	
	private VistaJuego vistaDelJuego;
	
	private HashMap<String, Pais> opcionesParaViajar;
	private HashMap<String, String> opcionesParaMostrar;
	
//---------------------------------------------------------------------------------------------------------
	
	public ControladorViaje(Juego juegoActual, VistaJuego vista) throws CasoNoIniciadoException {
		this.juego = juegoActual;
		
		this.vistaDelJuego = vista;
		
		this.opcionesParaViajar = this.crearOpcionesParaViajar();
		this.opcionesParaMostrar = this.crearOpcionesParaMostrar();
	}
	
//---------------------------------------------------------------------------------------------------------
	
	private HashMap<String, Pais> crearOpcionesParaViajar() throws CasoNoIniciadoException {
		HashMap<String, Pais> opciones = new HashMap<String, Pais>();
		
		ArrayList<Pais> paises = juego.verHaciaQuePaisesSePuedeViajar();
		
		if (paises != null) {
			Integer cantidadDePaises = paises.size();
			for (Integer i = 1; i < cantidadDePaises + 1; i++) {
				Pais pais = paises.get(i-1);
				opciones.put(i.toString(), pais);
			}
		}
			
		return opciones;
	}
	
	private HashMap<String, String> crearOpcionesParaMostrar() {
		HashMap<String, String> opciones = new HashMap<String, String>();
		
		for (Entry<String, Pais> opcion : opcionesParaViajar.entrySet()) {
			String opcionElegible = opcion.getKey();
			Pais pais = opcion.getValue();
		
			opciones.put(opcionElegible, pais.verNombreDeLaCapital());
		}
		
		return opciones;
	}
	
	private Pais procesarPaisParaViajar(BufferedReader entradaDeTeclado) throws IOException, CasoNoIniciadoException {
		String entrada = entradaDeTeclado.readLine();
		
		String opcionParaVolverAlMenuPrincipal = Integer.toString(0);
				
		while ( (!opcionesParaViajar.containsKey(entrada)) && (!opcionParaVolverAlMenuPrincipal.matches(entrada)) ) {
			VistaJuego.graficarMensajeDeOpcionElegidaIncorrecta(entradaDeTeclado);
			
			vistaDelJuego.graficarMenuDePosiblesPaisesParaViajar(opcionesParaMostrar);
			entrada = entradaDeTeclado.readLine();
		}
			
		return opcionesParaViajar.get(entrada);
	}

//---------------------------------------------------------------------------------------------------------
	
	public void procesarEntradasParaViajar(BufferedReader entradaDeTeclado) throws ParserConfigurationException, SAXException, IOException, CasoNoIniciadoException {
		vistaDelJuego.graficarMenuDePosiblesPaisesParaViajar(opcionesParaMostrar);	
		Pais paisElegido = this.procesarPaisParaViajar(entradaDeTeclado);
		
		if (paisElegido != null) {
			try {
				juego.viajarA(paisElegido);
			
				vistaDelJuego.seViajoAOtroPais();
			
				this.opcionesParaViajar = this.crearOpcionesParaViajar();
				this.opcionesParaMostrar = this.crearOpcionesParaMostrar();
			} 
			catch (PaisInvalidoParaViajarDesdeElActualException excepcion) {
				// Nunca se llega a la situacion en que se elija un pais que 
				// no este entre los propuestos.
				VistaJuego.graficarMensajeDeError(excepcion);
			}
		}
	}
	
	public void actualizar() throws CasoNoIniciadoException {
		this.opcionesParaViajar = this.crearOpcionesParaViajar();
		this.opcionesParaMostrar = this.crearOpcionesParaMostrar();
	}
}
